<script setup lang="ts">
import type { Directive, DirectiveBinding } from 'vue'

type Item = {
  name: string
  price: number
}

const items: Item[] = [
  {
    name: 'apple',
    price: 2,
  },
  {
    name: 'banana',
    price: 3,
  },
]

const vForDemo: Directive<HTMLElement, Item[]> = {
  mounted: (el: HTMLElement, binding: DirectiveBinding<Iterable<Item>>) => {
    const items = binding.value
    const tmpl = el.dataset.template

    if (!Array.isArray(items)) return
    if (!tmpl) return

    const parent = el.parentElement

    for (const item of items) {
      const newElement = document.createElement(el.tagName)
      newElement.innerHTML = tmpl.replace(/{{(.*?)}}/g, (match, key) =>
        key.trim() in item ? item[key.trim()] : match,
      )
      el.insertAdjacentElement('afterend', newElement)
    }
    parent?.removeChild(el)
  },
}
</script>

<template>
  <ul>
    <li v-for-demo="items" data-template="<p>{{name}} - {{price}}</p>"></li>
  </ul>
</template>
